<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>视频处理器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        }
        /* 遮罩层 */ .overlay { display: none; position: fixed; top: 0; left: 0;
        width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 1;
        } /* 弹窗样式 */ .modal { display: none; position: fixed; top: 50%; left: 50%;
        transform: translate(-50%, -50%); background: #fff; padding: 20px; box-shadow:
        0px 4px 6px rgba(0, 0, 0, 0.1); z-index: 2; width: 300px; text-align: center;
        } /* 关闭按钮 */ .close-btn { background-color: #f44336; color: white; border:
        none; padding: 5px 10px; cursor: pointer; border-radius: 5px; } .close-btn:hover
        { background-color: #d32f2f; }
        body {
            padding: 20px;
            background: #fff;
        }

        .container {
            display: flex;
            gap: 20px;
            max-width: 100%;
        }

        .main-content {
            flex: 1;
            width: 50%;
            max-width: 50%;
        }

        .right-panel {
            flex: 1;
            width: 50%;
            max-width: 50%;
        }

        .top-controls {
            display: flex;
            align-items: center;
            gap: 10px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }

        .required::before {
            content: '*';
            color: #ff4d4f;
            margin-right: 4px;
        }

        input[type="text"] {
            flex: 1;
            min-width: 200px;
            height: 32px;
            padding: 4px 11px;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            font-size: 20px;
        }

        .video-count {
            color: #666;
            white-space: nowrap;
        }

        .btn {
            height: 32px;
            padding: 4px 15px;
            border-radius: 6px;
            font-size: 20px;
            cursor: pointer;
            border: none;
            white-space: nowrap;
        }

        .btn-primary {
            background: #1890ff;
            color: white;
        }

        .btn-default {
            background: #fff;
            border: 1px solid #d9d9d9;
            color: #333;
        }

        .status-bar {
            margin: 16px 0;
            color: #666;
            font-size: 20px;
        }

        .red-text {
            color: #ff4d4f;
        }

        .table-container {
            border: 1px solid #f0f0f0;
            border-radius: 8px;
            overflow: hidden;
        }

        table {
            width: 100%;
            border-collapse: collapse;
        }

        th {
            background: #fafafa;
            padding: 12px;
            text-align: left;
            font-weight: normal;
            color: #666;
            border-bottom: 1px solid #f0f0f0;
        }

        .empty-state {
            padding: 48px 0;
            text-align: center;
            color: #999;
        }

        .empty-state img {
            width: 64px;
            height: 64px;
            margin-bottom: 8px;
        }

        .settings-section {
            margin-bottom: 20px;
        }

        .settings-title {
            font-size: 20px;
            margin-bottom: 12px;
        }

        .settings-content {
            display: grid;
            gap: 12px;
        }

        .control-row {
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 20px;
            flex-wrap: wrap;
        }

        .number-input {
            width: 60px;
            height: 24px;
            padding: 0 4px;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
        }

        .file-input {
            flex: 1;
            min-width: 150px;
            height: 32px;
            padding: 4px 11px;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            font-size: 20px;
            color: #999;
        }

        .section-header {
            display: flex;
            align-items: center;
            cursor: pointer;
            font-size: 20px;
            margin-bottom: 12px;
        }

        .section-header::before {
            content: '▼';
            display: inline-block;
            margin-right: 8px;
            transition: transform 0.3s;
            font-size: 20px;
        }

        .section-header.collapsed::before {
            transform: rotate(-90deg);
        }

        .section-content {
            margin-left: 20px;
        }

        .section-content.collapsed {
            display: none;
        }

        .effect-tags {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin-bottom: 16px;
        }

        .effect-tag {
            padding: 4px 12px;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            font-size: 20px;
            cursor: pointer;
            background: white;
        }

        .effect-tag:hover {
            border-color: #1890ff;
            color: #1890ff;
        }

        .circle-icon {
            color: #1890ff;
            font-size: 16px;
        }

        .progress-section {
            margin-top: 20px;
            padding: 16px;
            background: #f5f5f5;
            border-radius: 8px;
        }

        .progress-bar {
            width: 100%;
            height: 8px;
            background: #e6e6e6;
            border-radius: 4px;
            overflow: hidden;
            margin: 8px 0;
        }

        .progress-inner {
            width: 30%; /* 设置初始进度，可以通过JavaScript动态修改 */
            height: 100%;
            background: #1890ff;
            transition: width 0.3s ease;
        }

        .progress-text {
            text-align: right;
            font-size: 20px;
            color: #666;
        }

        @media (max-width: 1200px) {
            .container {
                flex-direction: column;
            }

            .main-content,
            .right-panel {
                width: 100%;
                max-width: 100%;
            }
        }
    </style>
    <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div class="container">

    <div id="overlay" class="overlay" onclick="closeModal()"></div>

    <div id="modal" class="modal">
        <p id="message">消息弹窗</p>
        <!-- TODO: 调整消息弹窗样式 -->
        <button class="close-btn" onclick="closeModal()">关闭</button>
    </div>

    <div class="main-content">
        <div class="top-controls">
            <label class="required">索引目录:</label>
            <label for="inputFile"></label><input type="text" id="inputFile" required readonly
                                                  placeholder="请选择视频文件夹" onclick="chooseFolder('inputFile')"
                                                  value="">
            <span class="video-count">视频数量: 0 </span>
            <div class="input-group">
                <label>导出目录:</label>
                <label for="clipOutput"></label><input type="text" required readonly
                                                       onclick="chooseOutputFolder('clipOutput')" id="clipOutput"
                                                       placeholder="请选择文件夹" value="">
            </div>
            <div class="button-group">
                <button class="btn btn-primary" onclick="openFile('clipOutput')">打开文件夹</button>
                <button class="btn btn-primary" onclick="start_work()">开始任务</button>
            </div>
        </div>

        <div class="status-bar">
            已选择<span class="red-text">0</span>个视频
            <input type="checkbox" id="selectAll" onclick="selectAll()">
            <label for="selectAll">选择全部</label>
        </div>

        <div class="table-container">
            <table>
                <thead>
                <tr>
                    <th style="width: 40px;">选择</th>
                    <th style="width: 60px;">序号</th>
                    <th>文件名</th>
                    <th style="width: 100px;">时长</th>
                    <th style="width: 100px;">大小</th>
                </tr>
                </thead>
                <tbody id="shotListBody">
                <!-- 动态生成的行将被插入这里 -->
                </tbody>
            </table>
        </div>
    </div>

    <div class="right-panel">
        <div class="settings-section">
            <div class="settings-title">去重方式:</div>
            <div class="settings-content">
                <div class="control-row">
                    <input type="checkbox" id="flip"> <label for="flip">镜像翻转</label>
                    <input type="checkbox" id="speed1"> <label for="speed1">随机速度</label>
                    <label>
                        <input type="number" class="speed1-input" id="speed1-min" step="0.1" value="1.0" max="2.0">
                        ~
                        <input type="number" class="speed1-input" id="speed1-max" value="1.5" step="0.1" max="2.0">
                    </label>
                </div>
                <div class="control-row">
                    <input type="checkbox" id="speed2"> <label for="speed2">随机抽帧</label>
                    每<label>
                    <input type="number" class="speed2-input" id="speed2-min" value="25" step="1" max="100">
                    ~

                    <input type="number" class="speed2-input" id="speed2-max" value="30" step="1" max="100">
                        帧抽一帧
                    </label>
                </div>
                <div class="control-row">
                    <input type="checkbox" id="imgOverlay"> <label for="imgOverlay">图片蒙层</label>
                    <label for="imgOverlay">不透明度:<input type="range" id="imgOverlay-slider" min="0" max="100" value="0" oninput="updateSliderValue('imgOverlay-slider', 'imgOverlay-slider-value')">
                        <span id="imgOverlay-slider-value"> 0% </span>
                    </label>
                    <label>
                        <input type="text" class="file-input" placeholder="请选择图片文件" readonly value="" id="imgOverlay-file"
                               onclick="chooseFile('imgOverlay-file', 'image')">
                    </label>
                </div>
                <div class="control-row">
                    <input type="checkbox" id="videoOverlay"> <label for="videoOverlay">视频蒙层</label>
                    <label for="imgOverlay">不透明度:<input type="range" id="videoOverlay-slider" min="0" max="100" oninput="updateSliderValue('videoOverlay-slider', 'videoOverlay-slider-value')"
                                                            value="0"><span id="videoOverlay-slider-value">0%</span></label>
                    <label>
                        <input type="text" class="file-input" placeholder="请选择图片文件" value=""
                               id="videoOverlay-file" readonly onclick="chooseFile('videoOverlay-file', 'video')">
                    </label>
                </div>
                <div class="control-row">
                    <input type="checkbox" id="colorAdjust"> <label for="colorAdjust">调色</label>
                    <label>亮度</label> <label><input type="number" id="light-input" class="number-input"
                                                      value="0.0" step="0.1" min="-1.0" max="1.0"></label>
                    <label>对比度</label><label><input type="number" id="contrast-input" class="number-input"
                                                       value="0.0" step="0.1" min="-2.0" max="2.0"></label>
                    <label>饱和度</label><label><input type="number" id="saturation-input" class="number-input"
                                                       value="0.0" step="0.1" min="0.0" max="3.0"></label>
                    <label>伽马</label><label> <input type="number" id="gamma-input" class="number-input"
                                                      value="0.0" step="0.1" min="0.1" max="10.0"></label>
                </div>
            </div>

            <div class="section">
                <div class="section-header">高级调色</div>
                <div class="section-content">
                    <div class="control-row">
                        <input type="checkbox" id="hsl">
                        <label for="hsl">HSL调色</label>
                        <label>色相</label> <label><input type="number" id="hsl-hue-input" class="number-input"
                                                          value="0.0" step="0.1" min="0.0"></label>
                        <label>饱和度</label><label><input type="number" id="hsl-saturation-input" class="number-input"
                                                           value="0.0" step="0.1" min="0.0" max="1.0"></label>
                        <label>亮度</label><label><input type="number" id="hsl-light-input" class="number-input"
                                                         value="0.0" step="0.1" min="0.0" max="1.0"></label>
                    </div>
                    <div class="control-row">
                        <input type="checkbox" id="colorBalance">
                        <label for="colorBalance">色彩平衡</label>
                        <label>阴影红色平衡</label> <label><input type="number" id="colorBalance-red-input"
                                                                  class="number-input" value="0.0" step="0.1" min="0.0"
                                                                  max="1.0"></label>
                        <label>阴影绿色平衡</label> <label><input type="number" id="colorBalance-green-input"
                                                                  class="number-input" value="0.0" step="0.1" min="0.0"
                                                                  max="1.0"></label>
                        <label>阴影蓝色平衡</label> <label><input type="number" id="colorBalance-blue-input"
                                                                  class="number-input" value="0.0" step="0.1" min="0.0"
                                                                  max="1.0"></label>
                        <label>中间调红色平衡</label> <label><input type="number" id="colorBalance-red-m-input"
                                                                    class="number-input" value="0.0" step="0.1"
                                                                    min="0.0" max="1.0"></label>
                        <label>中间调绿色平衡</label> <label><input type="number" id="colorBalance-green-m-input"
                                                                    class="number-input" value="0.0" step="0.1"
                                                                    min="0.0" max="1.0"></label>
                        <label>中间调蓝色平衡</label> <label><input type="number" id="colorBalance-blue-m-input"
                                                                    class="number-input" value="0.0" step="0.1"
                                                                    min="0.0" max="1.0"></label>
                        <label>高光红色平衡</label> <label><input type="number" id="colorBalance-red-l-input"
                                                                  class="number-input" value="0.0" step="0.1" min="0.0"
                                                                  max="1.0"></label>
                        <label>高光绿色平衡</label> <label><input type="number" id="colorBalance-green-l-input"
                                                                  class="number-input" value="0.0" step="0.1" min="0.0"
                                                                  max="1.0"></label>
                        <label>高光蓝色平衡</label> <label><input type="number" id="colorBalance-blue-l-input"
                                                                  class="number-input" value="0.0" step="0.1" min="0.0"
                                                                  max="1.0"></label>
                    </div>
                </div>
            </div>

            <div class="section">
                <div class="section-header">特效选择:</div>
                <div class="section-content">
                    <div class="effect-tags">
                        <button class="effect-tag">丁达尔光线</button>
                        <button class="effect-tag">下雨</button>
                        <button class="effect-tag">亮片</button>
                        <button class="effect-tag">像素扫描</button>
                        <button class="effect-tag">光线扫描</button>
                        <button class="effect-tag">冲击波</button>
                        <button class="effect-tag">冲屏闪粉</button>
                        <button class="effect-tag">圣诞光斑</button>
                        <button class="effect-tag">复古胶片</button>
                        <button class="effect-tag">夏日泡泡</button>
                    </div>
                </div>
            </div>

            <div class="section">
                <div class="section-header collapsed">更多特效</div>
                <div class="section-content collapsed">
                    <div class="effect-tags">
                        <button class="effect-tag">大爆炸</button>
                        <button class="effect-tag">大雪纷飞</button>
                        <button class="effect-tag">彩色雪花</button>
                        <button class="effect-tag">心花怒放</button>
                        <button class="effect-tag">恐怖故事</button>
                        <button class="effect-tag">水光影</button>
                        <button class="effect-tag">流光射门</button>
                        <button class="effect-tag">浪漫雪国2</button>
                        <button class="effect-tag">温暖烟雾</button>
                        <button class="effect-tag">炫彩</button>
                        <button class="effect-tag">烟火星河</button>
                        <button class="effect-tag">烟花光斑</button>
                        <button class="effect-tag">绚丽光斑</button>
                        <button class="effect-tag">缤纷粉花</button>
                        <button class="effect-tag">花火</button>
                        <button class="effect-tag">花瓣环绕</button>
                        <button class="effect-tag">萤火</button>
                        <button class="effect-tag">蒸汽喷雾</button>
                        <button class="effect-tag">蓝色闪电边框</button>
                        <button class="effect-tag">迪斯科</button>
                        <button class="effect-tag">金粉撒落</button>
                        <button class="effect-tag">金粉繁落</button>
                        <button class="effect-tag">金色雪花</button>
                        <button class="effect-tag">金色飘落</button>
                        <button class="effect-tag">闪点</button>
                        <button class="effect-tag">雨滴暴开</button>
                        <button class="effect-tag">雾气</button>
                        <button class="effect-tag">霓虹灯1</button>
                        <button class="effect-tag">电光火石</button>
                    </div>
                </div>
            </div>
            <div class="params-row">
                <div class="params-title">参数设置:</div>
                <div class="params-content">
                    <label> 不透明度:<input type="range" id="opacity-slider" step="1" min="0" max="100" value="0" oninput="updateSliderValue('opacity-slider', 'opacity-slider-value')"> <span id="opacity-slider-value">0%</span> </label>
                    <label> 开始位置:<input type="range" id="start-position-slider" step="1" min="0" max="100" value="0" oninput="updateSliderValue('start-position-slider','start-position-slider-value')"> <span id="start-position-slider-value">0%</span> </label>
                    <label>持续时长: <label>
                        <input type="number" class="number-input" value="0.5">
                        秒
                    </label></label>
                </div>
            </div>
        </div>
    </div>
</div>

<script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function () {
        let items = [];
        // Handle collapsible sections
        new QWebChannel(parent.qt.webChannelTransport, function (channel) {
            Bridge = channel.objects.Bridge;

            Bridge.started.connect(function (msg) {
                showModal(msg)
            });
            Bridge.failed.connect(function (msg) {
                showModal(msg)
            });
            Bridge.finished.connect(function (message) {
                showModal(message);
            });



            /*  文件操作方法  */
            // 选择的文件夹信号槽
            Bridge.select_folder_result.connect(function (eid, path) {
                document.getElementById(eid).value = path;
            });
            // 返回智能分镜目录
            Bridge.select_files_result.connect(function (eid, files, count) {
                // 渲染基础合成分镜列表
                const tbody = document.getElementById('shotListBody');
                if (!tbody) {
                    return;
                }
                let files_list = [];
                items = [];
                for (let file_item of files) {
                    files_list.push(`
                        <tr data-id="${file_item.id}">
                            <td><label>
                                <input type="checkbox" class="row-check" value="${file_item.file}">
                            </label></td>
                            <td>${file_item.id}</td>
                            <td>${file_item.file}</td>
                            <td>${file_item.duration}秒</td>
                            <td>${file_item.size}</td>
                        </tr>
                    `);
                    file_item.status = false;
                    items.push(file_item);
                }
                tbody.innerHTML = files_list.join('');
                document.getElementsByClassName("video-count")[0].innerText = "视频数量: " + count;
                bindEventListeners();
            });
            // 选择文件夹
            window.chooseFolder = function (eid) {
                Bridge.choose_folder_and_read_video_files(eid);
            };
            // 选择文件
            window.chooseFile = function (eid, suffix) {
                Bridge.choose_file(eid, suffix);
            };
            window.chooseOutputFolder = function (eid) {
                Bridge.choose_folder(eid);
            };
            window.openFile = function (eid) {
                let path = document.getElementById(eid).value;
                if (path) {
                    Bridge.open_file(path);
                }
            };

            window.start_work = function (){
                let input_files = [];
                for (let item of items){
                    if (item.status){
                        input_files.push(item.file)
                    }
                }
                if (input_files.length === 0){
                    showModal("请选择视频文件");
                    return;
                }
                if (document.getElementById("clipOutput").value === ""){
                    showModal("请选择输出目录");
                    return;
                }
                let tasks = {
                    "task": "视频去重",
                    "input_files": input_files,
                    "output_dir": document.getElementById("clipOutput").value,
                    "flip_status": document.getElementById("flip").checked,
                    "speed_up_status": document.getElementById('speed1').checked,
                    "extract_frames_status": document.getElementById('speed2').checked,
                    "add_img_overlay_status": document.getElementById('imgOverlay').checked,
                    "add_video_overlay_status": document.getElementById('videoOverlay').checked,
                    "adjust_video_status": document.getElementById('colorAdjust').checked,
                    "adjust_hsl_status": document.getElementById('hsl').checked,
                    "adjust_color_balance_status": document.getElementById('colorBalance').checked,
                    "kwargs": {
                        "speed_up_min": parseFloat(document.getElementById('speed1-min').value),
                        "speed_up_max": parseFloat(document.getElementById('speed1-max').value),
                        "extract_frames_min": parseInt(document.getElementById('speed2-min').value),
                        "extract_frames_max": parseInt(document.getElementById('speed2-max').value),
                        "img_overlay_path": document.getElementById('imgOverlay-file').value,
                        "img_overlay_opacity": parseInt(document.getElementById('imgOverlay-slider').value)/100,
                        "video_overlay_path": document.getElementById('videoOverlay-file').value,
                        "video_overlay_opacity": parseFloat(document.getElementById('videoOverlay-slider').value)/100,
                        "brightness": parseFloat(document.getElementById('light-input').value),
                        "contrast": parseFloat(document.getElementById('contrast-input').value),
                        "saturation": parseFloat(document.getElementById('saturation-input').value),
                        "gamma": parseFloat(document.getElementById('gamma-input').value),
                        "hue_shift": parseFloat(document.getElementById('hsl-hue-input').value),
                        "saturation_factor": parseFloat(document.getElementById('hsl-saturation-input').value),
                        "lightness_factor": parseFloat(document.getElementById('hsl-light-input').value),
                        "shadow_red": parseFloat(document.getElementById('colorBalance-red-input').value),
                        "shadow_green": parseFloat(document.getElementById('colorBalance-green-input').value),
                        "shadow_blue": parseFloat(document.getElementById('colorBalance-blue-input').value),
                        "midtones_red": parseFloat(document.getElementById('colorBalance-red-m-input').value),
                        "midtones_green": parseFloat(document.getElementById('colorBalance-green-m-input').value),
                        "midtones_blue": parseFloat(document.getElementById('colorBalance-blue-m-input').value),
                        "highlights_red": parseFloat(document.getElementById('colorBalance-red-l-input').value),
                        "highlights_green": parseFloat(document.getElementById('colorBalance-green-l-input').value),
                        "highlights_blue": parseFloat(document.getElementById('colorBalance-blue-l-input').value)
                    }
                };
                Bridge.start_worker(JSON.stringify(tasks));
            };


        });
        document.querySelectorAll('.section-header').forEach(header => {
            header.addEventListener('click', () => {
                header.classList.toggle('collapsed');
                header.nextElementSibling.classList.toggle('collapsed');
            });
        });
        let selected_video_count_elm = document.getElementsByClassName("red-text")[0];

        window.showModal = function (message) {
            document.getElementById("message").innerText = message;
            document.getElementById("overlay").style.display = "block";
            document.getElementById("modal").style.display = "block";
        };
        window.closeModal = function () {
            document.getElementById("overlay").style.display = "none";
            document.getElementById("modal").style.display = "none";
        };

        // 选择全部
        window.selectAll = function () {
            let selectAllCheckbox = document.getElementById("selectAll");
            let rowCheckboxes = document.querySelectorAll(".row-check");
            rowCheckboxes.forEach(checkbox => {
                checkbox.checked = selectAllCheckbox.checked;
            });
            if (selectAllCheckbox.checked) {
                selected_video_count_elm.innerText = rowCheckboxes.length;
                for (let item of items) {
                    item.status = true;
                }
            } else {
                for (let item of items) {
                    item.status = false;
                }
                selected_video_count_elm.innerText = 0;
            }
        };

        window.update_total = function () {
            let total_count = 0;
            for (let item of items) {
                if (item.status) {
                    total_count++;
                }
            }
            selected_video_count_elm.innerText = total_count;
        };

        // 更新滑块数值的显示
        window.updateSliderValue = function (sliderId, sliderValueId) {
            let slider = document.getElementById(sliderId);
            let sliderValue = document.getElementById(sliderValueId);
            sliderValue.textContent = slider.value + "%";
        };

        window.bindEventListeners = function () {

            document.querySelectorAll(".row-check").forEach(checkbox => {
                checkbox.addEventListener("change", function (event) {
                    if (checkbox.checked) {
                        for (let item of items) {
                            if (item.file === event.target.value) {
                                item.status = true;
                            }
                        }
                    } else {
                        for (let item of items) {
                            if (item.file === event.target.value) {
                                item.status = false;
                            }
                        }
                    }
                    update_total();
                });
            });
        }
    });
</script>
</body>
</html>